package hmis.pos.sys.shiro.filter;

import com.alibaba.fastjson.JSON;
import hmis.pos.Common.pojo.ApiResponse;
import hmis.pos.sys.shiro.token.JWTToken;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;


public class JWTFilter extends BasicHttpAuthenticationFilter {

    private Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    /**
     * 通过检测Header中是否包含Authorization字段
     * 判断用户是否想要登入
     *
     * @param request
     * @param response
     * @return
     */
    @Override
    protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
        HttpServletRequest req = (HttpServletRequest) request;
        String authorization = req.getHeader("Authorization");
        return authorization != null;
    }

    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws AuthenticationException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String authorization = httpServletRequest.getHeader("Authorization");

        JWTToken token = new JWTToken(authorization);
        // 提交到realm，如果错误会抛出异常
        getSubject(request, response).login(token);
        // 没抛出异常的话表明登入成功，返回true
        return true;
    }

    /**
     * 不直接拦截用户的请求，而是交给controller，通过subject.isAuthenticated()来判断
     *
     * @param request
     * @param response
     * @return
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        if (isLoginAttempt(request, response)) {
            try {
                executeLogin(request, response);
            } catch (AuthenticationException e){
                exceptionHandler(request,response,e);
            }
        }
        return true;
    }

    private void exceptionHandler(ServletRequest request,ServletResponse response, AuthenticationException e){
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        PrintWriter pout = null;
        try {
            pout = new PrintWriter(response.getWriter());
            String msg = e.getMessage();
            String result = JSON.toJSONString(new ApiResponse<>(401,msg));
            pout.append(result);
        } catch (IOException exception) {
            exception.printStackTrace();
        } finally {
            if(pout != null){
                pout.close();
            }
        }
    }

}
